#include "facedetector.h"
#include "ui_facedetector.h"
#include <opencv2/opencv.hpp>
#include <QImage>
#include <QPixmap>
#include <QMessageBox>
#include "userdb.h"

void FaceDetector::getFrame()
{
    cv::Mat frame;
    cap >> frame;
    cv::Mat src = frame.clone();
    //检测人脸
    faceDetector = cv::FaceDetectorYN::create(fd_model.toStdString(), "", src.size());
    faceDetector->detect(src, face);
    if (face.rows < 1) {
        cv::cvtColor(src, src, cv::COLOR_BGR2RGB);
        QImage img{src.data, src.cols, src.rows, int(src.step[0]), QImage::Format_RGB888};
//        QImage img{src.data, src.cols, src.rows, int(src.step[0]), QImage::Format_BGR888};
        ui->label_img->setPixmap(QPixmap{QPixmap::fromImage(img)});
        return;
    }
    for (int i = 0; i < face.rows; ++i) {
        cv::rectangle(src, cv::Rect(
                                    face.at<float>(i, 0),
                                    face.at<float>(i, 1),
                                    face.at<float>(i, 2),
                                    face.at<float>(i, 3)
                           ), cv::Scalar(0, 0, 255), 2);
    }
    cv::resize(src, src, cv::Size{ui->label_img->width(), ui->label_img->height()});
    cv::cvtColor(src, src, cv::COLOR_BGR2RGB);
    QImage img{src.data, src.cols, src.rows, int(src.step[0]), QImage::Format_RGB888};
//    QImage img{src.data, src.cols, src.rows, int(src.step[0]), QImage::Format_BGR888};
    ui->label_img->setPixmap(QPixmap{QPixmap::fromImage(img)});
    //人脸匹配
    cv::Mat aligned_face;
    faceRecongnizer->alignCrop(frame, face.row(0), aligned_face);
    cv::Mat feature;
    faceRecongnizer->feature(aligned_face, feature);
    feature = feature.clone();
    QString name = UserDB::instance().getNameByFeature(feature, faceRecongnizer);
    if (name != "NULL") {
        ui->lineEdit_result->setText(name + "打卡成功");
        UserDB::instance().UserClockin(user_id);
    } else {
        ui->lineEdit_result->setText("请录入人脸信息");
    }
}

FaceDetector::FaceDetector(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::FaceDetector)
{
    ui->setupUi(this);
    ui->pushButton_cancel->setEnabled(false);
    ui->pushButton_clock_in->setEnabled(true);
    //winsdow
#ifdef _WIN32
   fd_model = "../../face_detector_models/yunet.onnx";
   fr_model = "../../face_detector_models/face_recognizer_fast.onnx";
#else
    //linux
    fd_model = "../FaceDetector/face_detector_models/yunet.onnx";
    fr_model = "../FaceDetector/face_detector_models/face_recognizer_fast.onnx";
#endif
    faceRecongnizer = cv::FaceRecognizerSF::create(fr_model.toStdString(), "");
    this->setWindowTitle("打卡界面");
    this->setWindowIcon(QIcon{":/Image/myheart.png"});
    timer = new QTimer(this);
    connect(timer, &QTimer::timeout, this, &FaceDetector::getFrame);
    this->setFixedSize(1024, 600);
}

void FaceDetector::setID(int id)
{
    this->user_id = id;
    ui->label->setText("欢迎登录! " + QString::number(id));
}

FaceDetector::~FaceDetector()
{
    delete ui;
}

/**
 * @brief FaceDetector::on_pushButton_clock_in_clicked
 * 签到打卡,打开摄像头
 */
void FaceDetector::on_pushButton_clock_in_clicked()
{
    ui->pushButton_cancel->setEnabled(true);
    ui->pushButton_clock_in->setEnabled(false);
    timer->start(200);
    cap.open(0);
}

/**
 * @brief FaceDetector::on_pushButton_cancel_clicked
 * 取消打卡，关闭摄像头
 */
void FaceDetector::on_pushButton_cancel_clicked()
{
    cap.release();
    timer->stop();
    ui->pushButton_cancel->setEnabled(false);
    ui->pushButton_clock_in->setEnabled(true);
}

/**
 * @brief FaceDetector::on_pushButton_record_clicked
 * 录入人脸信息
 */
void FaceDetector::on_pushButton_record_clicked()
{
    cv::Mat frame;
    cap >> frame;
    cv::Mat src = frame.clone();
    //检测人脸
    faceDetector = cv::FaceDetectorYN::create(fd_model.toStdString(), "", src.size());
    faceDetector->detect(src, face);
    for (int i = 0; i < face.rows; ++i) {
        cv::rectangle(src, cv::Rect(
                               face.at<float>(i, 0),
                               face.at<float>(i, 1),
                               face.at<float>(i, 2),
                               face.at<float>(i, 3)
                               ), cv::Scalar(0, 0, 255), 2);
    }
    cv::resize(src, src, cv::Size{ui->label_img->width(), ui->label_img->height()});
    cv::cvtColor(src, src, cv::COLOR_BGR2RGB);
    QImage img{src.data, src.cols, src.rows, int(src.step[0]), QImage::Format_RGB888};
//    QImage img{src.data, src.cols, src.rows, int(src.step[0]), QImage::Format_BGR888};
    ui->label_img->setPixmap(QPixmap{QPixmap::fromImage(img)});
    //人脸匹配
    cv::Mat aligned_face;
    faceRecongnizer->alignCrop(frame, face.row(0), aligned_face);
    cv::Mat feature;
    faceRecongnizer->feature(aligned_face, feature);
    feature = feature.clone();
    QString name = UserDB::instance().getNameByFeature(feature, faceRecongnizer);
    ui->lineEdit_result->setText(name + "打卡成功");
    bool res = UserDB::instance().insertFeatureByID(user_id, feature);
    if (res) {
        QMessageBox::information(this, "tip", "录入人脸成功");
    } else {
        QMessageBox::information(this, "tip", "录入人脸失败");
    }
}


void FaceDetector::on_pushButton_back_clicked()
{
    ui->label_img->clear();
    if (cap.isOpened()) {
        this->on_pushButton_cancel_clicked();
    }
    this->hide();
    emit back();
}

